package cn.jarlen.photoedit.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;

import cn.jarlen.photoedit.net.Constant;

public class FileUtils
{

	public static String SDCARD_PAHT = Environment
			.getExternalStorageDirectory().getPath();

	public static String DCIMCamera_PATH = Environment
			.getExternalStorageDirectory() + "/DCIM/Camera/";

	/**
	 * 检测sdcard是否可用
	 * 
	 * @return true为可用; false为不可用
	 */
	public static boolean isSDAvailable()
	{
		String status = Environment.getExternalStorageState();
		if (!status.equals(Environment.MEDIA_MOUNTED))
			return false;
		return true;
	}

	/**
	 * 保持长宽比缩小Bitmap
	 * 
	 * @param bitmap
	 * @param maxWidth
	 * @param maxHeight
	 * @return
	 */
	public static Bitmap resizeBitmap(Bitmap bitmap, int maxWidth, int maxHeight)
	{

		int originWidth = bitmap.getWidth();
		int originHeight = bitmap.getHeight();

		// no need to resize
		if (originWidth < maxWidth && originHeight < maxHeight)
		{
			return bitmap;
		}

		int width = originWidth;
		int height = originHeight;

		// 若图片过宽, 则保持长宽比缩放图片
		if (originWidth > maxWidth)
		{
			width = maxWidth;

			double i = originWidth * 1.0 / maxWidth;
			height = (int) Math.floor(originHeight / i);

			bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
		}

		// 若图片过长, 则从上端截取
		if (height > maxHeight)
		{
			height = maxHeight;
			bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
		}

		return bitmap;
	}

	public static Bitmap ResizeBitmap(Bitmap bitmap, int scale)
	{
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		Matrix matrix = new Matrix();
		matrix.postScale(1 / scale, 1 / scale);

		Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		bitmap.recycle();
		return resizedBitmap;
	}

	public static String compressJEPG(String srcPath, int maxSize)
	{

		String outPath = null;

		File srcFile = new File(srcPath);

		if (!srcFile.exists())
		{
			return outPath;
		}

		String rootPath = srcFile.getParentFile().getAbsolutePath();

		Options option = new Options();
		option.inSampleSize = 1;
		Bitmap srcBitmap = BitmapFactory.decodeFile(srcPath, option);

		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		int options = 100;

		// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
		srcBitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);

		// 循环判断如果压缩后图片是否大于maxSize kb,大于继续压缩
		while (baos.toByteArray().length > maxSize * 1000)
		{
			// 重置baos即清空baos
			baos.reset();
			options -= 10;// 每次都减少5
			// 这里压缩options%，把压缩后的数据存放到baos中
			srcBitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
		}

		// 把压缩后的数据baos存放到ByteArrayInputStream中
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());

		// 把ByteArrayInputStream数据生成图片
		Bitmap resultBitmap = BitmapFactory.decodeStream(isBm, null, null);

		String outName = getNewFileName();

		outPath = rootPath + "/" + outName + ".jpg";
		writeImage(resultBitmap, outPath, 95);

		if (srcBitmap != null)
		{
			srcBitmap.recycle();
			srcBitmap = null;
		}

		File outFile = new File(outPath);
		if (!outFile.exists())
		{
			if (resultBitmap != null)
			{
				resultBitmap.recycle();
				resultBitmap = null;
			}
			return null;
		}

		if (resultBitmap != null)
		{
			resultBitmap.recycle();
			resultBitmap = null;
		}

		return outPath;
	}

	public static String getNewFileName()
	{
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		Date curDate = new Date(System.currentTimeMillis());

		return formatter.format(curDate);
	}

	/**
	 * 
	 * @param context
	 *            上下文
	 * 
	 * @param bm
	 *            要保存的bitmap
	 * 
	 * @param name
	 *            保存的名字 可为null,就根据时间自定义一个文件名
	 * 
	 * @return 以“.jpg”格式保存至相册
	 * 
	 */
	public static Boolean saveBitmapToCamera(Context context, Bitmap bm,
			String name)
	{

		File file = null;

		if (name == null || name.equals(""))
		{
			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
			Date curDate = new Date(System.currentTimeMillis());
			name = formatter.format(curDate) + ".jpg";
		}

		file = new File(DCIMCamera_PATH, name);
		if (file.exists())
		{
			file.delete();
		}

		try
		{
			FileOutputStream out = new FileOutputStream(file);
			bm.compress(Bitmap.CompressFormat.PNG, 100, out);
			out.flush();
			out.close();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
			return false;

		} catch (IOException e)
		{

			e.printStackTrace();
			return false;
		}

		// Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		// Uri uri = Uri.fromFile(file);
		// intent.setData(uri);
		// context.sendBroadcast(intent);

		return true;
	}

	/**
	 * 
	 * @param bitmap
	 * @param destPath
	 * @param quality
	 */
	public static void writeImage(Bitmap bitmap, String destPath, int quality)
	{
		try
		{
			if (createFile(destPath))
			{
				FileOutputStream out = new FileOutputStream(destPath);
				if (bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out))
				{
					out.flush();
					out.close();
					out = null;
				}
			}
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	public static String writeImageToCustomerCamera(Bitmap bit)
	{
		String imgName = getNewFileName();

		String imagPath = Constant.Camera_Customer_Path + imgName + ".jpg";
		File imageFile = new File(imagPath);
		if (imageFile == null && !imageFile.exists())
		{
			imageFile.mkdirs();
		}
		writeImage(bit, imagPath, 100);
		return imagPath;
	}

	public static boolean createFile(String filePath)
	{
		try
		{
			File file = new File(filePath);
			if (!file.exists())
			{
				if (!file.getParentFile().exists())
				{
					file.getParentFile().mkdirs();
				}

				return file.createNewFile();
			}
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * 删除一个文件
	 * 
	 * @param filePath
	 *            要删除的文件路径名
	 * @return true if this file was deleted, false otherwise
	 */
	public static boolean deleteFile(String filePath)
	{
		try
		{
			File file = new File(filePath);
			if (file.exists())
			{
				return file.delete();
			}
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 删除 directoryPath目录下的所有文件，包括删除删除文件夹
	 * 
	 * @param dir
	 */
	public static void deleteDirectory(File dir)
	{
		if (dir.isDirectory())
		{
			File[] listFiles = dir.listFiles();
			for (int i = 0; i < listFiles.length; i++)
			{
				deleteDirectory(listFiles[i]);
			}
		}
		dir.delete();
	}

	public static Bitmap getImageFromAssetsFile(Context context, String fileName)
	{
		Bitmap image = null;
		AssetManager am = context.getResources().getAssets();
		try
		{
			InputStream is = am.open(fileName);
			image = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e)
		{
			e.printStackTrace();
		}

		return image;

	}

	/**
	 * 获取本地图片数据库中的第一张图片的路径
	 * 
	 * @param context
	 * 
	 * @return 图片路径
	 * 
	 */
	public static String getAlbumThumbnailPath(Context context)
	{
		String columns[] = new String[]{Media.DATA, Media._ID, Media.TITLE,
				Media.DISPLAY_NAME, Media.SIZE};

		Cursor cursor = context.getContentResolver().query(
				Media.EXTERNAL_CONTENT_URI, columns, null, null, null);

		// int photoIndex = cursor.getColumnIndexOrThrow(Media.DATA);
		// photoNameIndex = cursor.getColumnIndexOrThrow(Media.DISPLAY_NAME);
		// photoIDIndex = cursor.getColumnIndexOrThrow(Media._ID);
		// photoTitleIndex = cursor.getColumnIndexOrThrow(Media.TITLE);
		// photoSizeIndex = cursor.getColumnIndexOrThrow(Media.SIZE);

		if (cursor == null)
		{
			return null;
		}

		// 获取图片总数
		int totalNum = cursor.getCount();

		if (totalNum <= 0)
		{
			return null;
		}
		cursor.moveToFirst();
		int photoIndex = cursor.getColumnIndexOrThrow(Media.DATA);
		String path = cursor.getString(photoIndex);
		return path;
	}

	/**
	 * <br>
	 * 功能简述:4.4及以上获取图片的方法 <br>
	 * 功能详细描述: <br>
	 * 注意:
	 * 
	 * @param context
	 * @param uri
	 * @return
	 */
	@TargetApi(Build.VERSION_CODES.KITKAT)
	public static String getPath(final Context context, final Uri uri)
	{

		final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

		// DocumentProvider
		if (isKitKat && DocumentsContract.isDocumentUri(context, uri))
		{
			// ExternalStorageProvider
			if (isExternalStorageDocument(uri))
			{
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];

				if ("primary".equalsIgnoreCase(type))
				{
					return Environment.getExternalStorageDirectory() + "/"
							+ split[1];
				}
			}
			// DownloadsProvider
			else if (isDownloadsDocument(uri))
			{

				final String id = DocumentsContract.getDocumentId(uri);
				final Uri contentUri = ContentUris.withAppendedId(
						Uri.parse("content://downloads/public_downloads"),
						Long.valueOf(id));

				return getDataColumn(context, contentUri, null, null);
			}
			// MediaProvider
			else if (isMediaDocument(uri))
			{
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];

				Uri contentUri = null;
				if ("image".equals(type))
				{
					contentUri = Media.EXTERNAL_CONTENT_URI;
				} else if ("video".equals(type))
				{
					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
				} else if ("audio".equals(type))
				{
					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
				}

				final String selection = "_id=?";
				final String[] selectionArgs = new String[]{split[1]};

				return getDataColumn(context, contentUri, selection,
						selectionArgs);
			}
		}
		// MediaStore (and general)
		else if ("content".equalsIgnoreCase(uri.getScheme()))
		{

			// Return the remote address
			if (isGooglePhotosUri(uri))
				return uri.getLastPathSegment();

			return getDataColumn(context, uri, null, null);
		}
		// File
		else if ("file".equalsIgnoreCase(uri.getScheme()))
		{
			return uri.getPath();
		}

		return null;
	}

	public static String getDataColumn(Context context, Uri uri,
			String selection, String[] selectionArgs)
	{

		Cursor cursor = null;
		final String column = "_data";
		final String[] projection = {column};

		try
		{
			cursor = context.getContentResolver().query(uri, projection,
					selection, selectionArgs, null);
			if (cursor != null && cursor.moveToFirst())
			{
				final int index = cursor.getColumnIndexOrThrow(column);
				return cursor.getString(index);
			}
		} finally
		{
			if (cursor != null)
				cursor.close();
		}
		return null;
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is ExternalStorageProvider.
	 */
	public static boolean isExternalStorageDocument(Uri uri)
	{
		return "com.android.externalstorage.documents".equals(uri
				.getAuthority());
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is DownloadsProvider.
	 */
	public static boolean isDownloadsDocument(Uri uri)
	{
		return "com.android.providers.downloads.documents".equals(uri
				.getAuthority());
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is MediaProvider.
	 */
	public static boolean isMediaDocument(Uri uri)
	{
		return "com.android.providers.media.documents".equals(uri
				.getAuthority());
	}

	/**
	 * @param uri
	 *            The Uri to check.
	 * @return Whether the Uri authority is Google Photos.
	 */
	public static boolean isGooglePhotosUri(Uri uri)
	{
		return "com.google.android.apps.photos.content".equals(uri
				.getAuthority());
	}

}
